// 封装自定义hook useHistory
import { useSyncExternalStore } from "react";
/**
 * useSyncExternalStore
 * 第一个参数 subscribe：用来订阅数据源的变化，接收一个回调函数，在数据源更新时调用该回调函数。
 * 第二个参数 getSnapshot：获取当前数据源的快照（当前状态）。
 * 第三个参数 getServerSnapshot?：在服务器端渲染时用来获取数据源的快照。
 */

/**
 * description: 自定义hook useHistory
 * @param key 键
 * @param defaultValue 默认值
 */

export const useHistory = () => {
  const subscribe = (callback: () => void) => {
    window.addEventListener("popstate", callback);
    window.addEventListener("hashchange", callback);
    return () => {
      window.removeEventListener("popstate", callback);
      window.removeEventListener("hashchange", callback);
    };
  };
  /**
   * 如果 getSnapshot 返回值不同于上一次，React 会重新渲染组件。这就是为什么，如果总是返回一个不同的值，会进入到一个无限循环，并产生这个报错。
   * Uncaught (in promise) Error: Maximum update depth exceeded.
   * This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.
   *  React limits the number of nested updates to prevent infinite loops
   */
  const getSnapshot = () => {
    // 解决 ：// 只有在 todos 真的发生变化时，才更新快照
    return window.location.href;
  };

  const push = (path: string) => {
    window.history.pushState(null, "", path);
    window.dispatchEvent(new PopStateEvent("popstate"));
  };

  const replace = (path: string) => {
    window.history.replaceState(null, "", path);
    window.dispatchEvent(new PopStateEvent("popstate"));
  };

  const res = useSyncExternalStore(subscribe, getSnapshot);
  return [res, push, replace] as const;
};
